'use strict';
// 免费存储空间大小
const UserStorageSpace = Math.pow(1024, 3)

const db = uniCloud.database();
const dbCmd = db.command
const $ = db.command.aggregate
const SMS = require('../../SMS/index.js')
const tools = require("../../tools/index.js")
const alioss = require('../../oss/index.js')
const Encryption_decryption = require('../../JSEncrypt/index.js')

// const ToDecryption = async (val) => Encryption_decryption.$JSEncrypt.decrypt(val) // 非对称解密

// let SMS_cache = new Map()
// // 轮询清除验证码缓存(1分钟清一次)
// setInterval(()=>{
// 	SMS_cache.forEach((values,keys)=>{
// 	    if((new Date().getTime()) - values.split(',')[1]>60000){
// 			SMS_cache.delete(keys) // 超过60秒删除缓存
// 		}
// 	})
// },1000*60)




// 获取短信验证码
exports.getSMSInterface = async (body_data) => {
	let {SMSType,account} = body_data
	if (!SMSType || !account) return {
		code: 200,
		msg: "参数错误"
	}
	let RandomCode = Math.random().toFixed(6).slice(2)	// 6位随机验证码

	try{
		let affair = await db.runTransaction(async transaction => {
			// 判断用户的账号是否申请过验证码
			let IsApplySmsCode = await transaction.collection('SMSCache').where({account}).get()
			// 该账号申请过验证码
			let result = ''
			if (IsApplySmsCode.data.length >= 1) {
				result = await transaction.collection('SMSCache').doc(IsApplySmsCode.data[0]._id).update({
					verCode: RandomCode,
					SMSType,
					agingTime: new db.serverDate()
				})
			} else {
				result = await transaction.collection('SMSCache').add({
					account,
					verCode: RandomCode,
					SMSType,
					agingTime: new db.serverDate()
				})
			}
			
			// 短信配置表
			let SMSconfig = {
				phone: account,
				data: {
					code: RandomCode,
					action: '洋盘',
					expMinute: '5',
					brand: '洋盘'
				}
			}
			// 用于解构数据
			let configs = null
			if (SMSType === 'register') {
				configs = SMS.SMSConfig.register
			} else if (SMSType === 'login') {
				configs = SMS.SMSConfig.login
			} else {
				configs = SMS.SMSConfig.ResetPwd
			}
			
			// 加层判断（在短信验证登录下） 如果未注册过的用户直接用短信验证码登录不给验证码
			if (SMSType === 'login' || SMSType === 'ResetPwd') {
				let SelUserIsExist = await db.collection('User').where({account}).count()
				if (SelUserIsExist.total === 0) return {
					code: 204,
					msg: "该账户未曾注册过！"
				}
			}
			
			// 发送短信
			let smsRes = await uniCloud.sendSms(Object.assign(SMSconfig, configs))
			return {
				code: 200,
				msg: "短信已发送",
				result,
				smsRes
			}
		})
		return affair
	}catch(e){
		console.log(e)
		return{
			code:500,
			msg:"内部错误"
		}
	}
	
}

// 注册接口 
exports.APIRegister = async function(body_data) {
	let returnData = { code: 200,msg: "参数错误~" }
	let {account,pwd,verCode} = body_data
	if (!account || !pwd || !verCode) {
		return returnData
	}
	try {
		let affair = await db.runTransaction(async transaction => {
			// 判断用户的账号是否存在
			let SelUserIsExist =  await transaction.collection('User').where({account}).count();
			if (SelUserIsExist.total >= 1) return {code: 204,msg: "该账户已注册过！"};
			
			/* 查询短信信息 --->>>> 校验操作*/
			let selSMSCodeRes = await transaction.collection('SMSCache').where({account}).get() 
			// 短信未发送
			if(selSMSCodeRes.data.length == 0){return {code: 204,msg: "短信未发送"}}
			// 该验证码已过期
			if ((new db.serverDate() - selSMSCodeRes.data[0].agingTime) > 60000 * 5) {return {code: 204,msg: "该验证码已过期，请重新获取！"}} 
			// 验证码错误
			if (verCode != selSMSCodeRes.data[0].verCode) {return {code: 204,msg: "验证码错误！"}}
			
			
			
			let AddJson = {
				account,
				pwd,
				registerTime: new Date(),
				Token: null,
				UserStorageSpace
			}
			let result = await transaction.collection('User').add(AddJson)
			if(!result.id){await transaction.rollback('注册成功未成功~')}
			let SuccensUserInfo = await transaction.collection('User').doc(result.id).get()
			// 注册成功
			let res_oss = await alioss.CreatFolder(account); // 创建oss文件夹
			if (res_oss.code === 500) {return {msg: "阿里云文件存储报错",err}}
			// SMS_cache.delete(`${account}`)  // 注册成功后，立即删除验证码缓存
			return {
				msg: "注册成功~",
				code: 200,
				data:SuccensUserInfo.data
			}
		})
		return affair
	} catch (e) {
		console.log(e)
		return {
			msg: "内部错误~",
			code: 500
		}
	}
}

// 第三方注册/登录(包括登录附加STS权限)
exports.APIRegister_thirdparty = async function(body_data) {
	let returnData = { code: 200,msg: "参数错误~" }
	let {way,openid,Nickname,sex,avatar} = body_data
	if (!way || !openid) {return returnData}
	// 先查询openid 如果存在返回token 不存在注册新用户
	// 一个根据账号创建OSS文件夹的思路  没用手机号了 直接用日期时间
	try {
		const affair = await db.runTransaction(async transaction => {
			let Sts = await alioss.assumeRole() // 临时权限
			// 查询该OpenID是否注册过
			let SelRes = await transaction.collection('User').where({openid}).get();
			let Token = tools.create_token(); // 生成一个token
			let RandomAccount = tools.create_timeName(); // 生成一个按日期的账号
					
			// 注册过
			if (SelRes.data.length > 0) {
				
				
				let result = await transaction.collection('User').where({openid}).update({Token: Token})
				if(result.updated===0) { return await transaction.rollback('更新用户数据失败') }
				
				returnData.msg='登录成功~'
				returnData.token=Token
				returnData.data= SelRes.data[0]
				returnData.Sts = Sts
				return returnData
				
			
			// 未注册过
			} else {
				
				// 插入
				let result = await transaction.collection('User').add({
					way,openid,registerTime: new Date(),Token: Token,
					account: RandomAccount,Nickname,sex,avatar,UserStorageSpace
				})
				if(!result.id) { return await transaction.rollback('更新用户数据失败') }
				
				// 查询
				SelRes = await transaction.collection('User').where({openid}).get();
				let res_oss = await alioss.CreatFolder(SelRes.data[0].account);
				if (res_oss.code === 500) {await transaction.rollback('阿里云文件存储报错')}
				return {
					code: 200,
					msg: "注册成功~",
					token: Token,
					data: SelRes.data[0],
					Sts
				}
				
			}
			
			
		})	
		return affair
	} catch (e) {
		console.error(`事务失败`, e)
		return {
			msg: '内部错误~',
			code: 500
		}
	}


}

// 登录接口（密码登录/短信验证码登录）
exports.APILogin = async function(body_data) {
	let {account,pwd,verCode} = body_data;
	if (!account) {return {code:200,msg: "参数错误"}};
	let Token = tools.create_token()
	// 解密
	// account = Encryption_decryption.$JSEncrypt.decrypt(account)
	pwd ? pwd = Encryption_decryption.$JSEncrypt.decrypt(pwd) :""
	
	try {
		const affair = await db.runTransaction(async transaction => {
			
			// 验证码登录（登录前判断短信的是否有效）
			if (verCode) {
				let selSMSCodeRes = await transaction.collection('SMSCache').where({account}).get()
				if(selSMSCodeRes.data.length===0) {return {code: 204,msg: "短信未发送"}}
				
				if ((new db.serverDate() - selSMSCodeRes.data[0].agingTime) > 60000 * 5) {
					return {code: 204,msg: "该验证码已过期，请重新获取！"}
				} else {
					if (verCode != selSMSCodeRes.data[0].verCode) {return {code: 204,msg: "验证码错误！"}}
					let Sts = await alioss.assumeRole()
					let AccountIsExist = await transaction.collection('User').where({account}).get()
					if(AccountIsExist.data.length===0){return {code:204,msg:"该账号未注册！"}}
					let ReashToken = await transaction.collection('User').where({account}).update({Token})
					return {
						code: 200,
						msg: '登录成功~',
						Token,
						Sts
					}
				}
			}
			
			// 普通的账号密码登录
			// 查询数据
			let res = await transaction.collection('User').where({account,pwd}).get()
			// 账号密码错误
			if (res.data.length === 0 || res.data === null) {return {code: 204,msg: "账号密码错误"}}
			// 数据存在
			let ReashToken = await transaction.collection('User').doc(res.data[0]._id).update({Token})
			if (ReashToken.updated > 0) {
				let Sts = await alioss.assumeRole()
				return {
					code: 200,
					msg: '登录成功~',
					Token,
					Sts
				}
			}
		})
		return affair
	}catch(e){
		console.error(`事务失败`, e)
		return {
			msg: '内部错误~',
			code: 500
		}
	}
}

// 获取个人信息
exports.APIGetUserinfo = async function(body_data) {
	let {Token} = body_data
	try{
		let res = await db.collection('User').where({Token}).get()
		if(res.data.length>0){
			return {
				msg: "获取个人信息成功~",
				code: 200,
				result: res.data[0]
			}
		}else{
			return {
				msg: "该用户未存在~",
				code: 204,
			}
		}
	}catch(e){
		return {
			code:500,
			msg:'内部错误~'
		}
	}
	
}

// 修改个人信息
exports.APIUpdUserinfo = async function(body_data) {
	let {
		Token,UserInfo,
		account,newPwd,avatar,sex,Nickname,birth,Region,introduce
	} = body_data, arr = [], json = {}
	try{
		
		/* 处理参数操作 */
		let celue = ['account','newPwd','avatar', 'sex', 'Nickname', 'birth', 'Region', 'introduce']
		for (let i = 0, item; item = celue[i]; i++) {
			arr.push(body_data[item])
		}
		
		// 改单个属性好像，我也forget了
		let Index = arr.findIndex(i => i != null)
		if (Index == -1) return {
			code: 204,
			msg: "参数错误~"
		}
		json[celue[Index]] = body_data[celue[Index]]
		newPwd? json['newPwd'] = Encryption_decryption.$JSEncrypt.decrypt(newPwd) :"" // 重置密码的时候解密
		
		const affair = await db.runTransaction(async transaction => {
			let UpdateRes = await transaction.collection('User').doc(UserInfo._id).update(json)
			if(UpdateRes.updated ===0) return await transaction.rollback('更新用户数据失败') 
			UserInfo = await transaction.collection('User').where({_id:UserInfo._id}).get()
			return {
				msg: "修改个人信息成功~",
				code: 200,
				data: UserInfo.data[0]
			}
		})
		return affair
	}catch(e){
		return {
			code:500,
			msg:'内部错误~'
		}
	}
	
}

// 校验验证码是否正确
exports.CheckVerCode = async (body_data) => {
	let {verCode,account} = body_data
	if (!verCode || !account) return {
		code: 204,
		msg: "参数错误"
	}
	// 登录前判断短信的是否有效
	let selSMSCodeRes = await db.collection('SMSCache').where({account}).get()
	if(selSMSCodeRes.data.length===0) {return {code: 204,msg: "短信未发送"}}

	// 验证码登录逻辑
	if ((new db.serverDate() - selSMSCodeRes.data[0].agingTime) > 60000 * 5) {
		return {
			code: 204,
			msg: "该验证码已过期，请重新获取！"
		}
	} else {
		if (verCode != selSMSCodeRes.data[0].verCode) {
			return {
				code: 204,
				msg: "验证码错误！"
			}
		} else {
			return {
				code: 200,
				msg: "验证成功！"
			}
		}
	}
	
}

// 修改个人密码
exports.APIUpdatePwd = async (body_data) => {
	let {account,newPwd} = body_data
	if (!account || !newPwd) return {
		code: 200,
		msg: "参数错误"
	}
	newPwd = Encryption_decryption.$JSEncrypt.decrypt(newPwd)

	try {
		const affair = await db.runTransaction(async transaction => {
			let SelRes = await transaction.collection('User').where({account}).get()
			let res = await transaction.collection('User').doc(SelRes.data[0]._id).update({
				pwd: newPwd
			})
			// await transaction.rollback('更新数据库错误')
			return res
		})
		return {
			code: 200,
			msg: "设置成功~",
			data: affair
		}
	} catch (e) {
		console.error(`事务失败`, e)
		return {
			msg: '内部错误~',
			code: 500
		}
	}

}
